import pandas as pd
import numpy as np

# 定义按类别众数填充的函数
def fill_with_group_mode(df, df2, group_col, fill_cols):
    """
    按指定列分组，用各组的众数填充指定列的空值

    参数:
    df: 要处理的数据框
    group_col: 作为分组依据的列名
    fill_cols: 需要填充的列名列表
    """
    for col in fill_cols:
        # 计算每个类别的众数
        mode_values = df.groupby(group_col)[col].transform(lambda x: x.mode()[0] if not x.mode().empty else np.nan)
        # 填充空值
        df[col] = df[col].fillna(mode_values)
        df2[col] = df2[col].fillna(mode_values)
    return df, df2


others = list(data_train.columns)[:-1]
X_train, X_test = fill_with_group_mode(data_train, data_test, 'Personality', others)
print(data_train.head(10))
from sklearn.preprocessing import LabelEncoder

le = LabelEncoder()
y_train = le.fit_transform(data_train['Personality'])
X_train = X_train[list(X_train.columns)]
X_train.drop("Personality", axis=1, inplace=True)
print(X_train.head())
from sklearn.preprocessing import OneHotEncoder

# 初始化编码器
ohe = OneHotEncoder(handle_unknown='ignore', sparse=False)
category_column = ["Stage_fear", "Drained_after_socializing"]
# 只使用训练集拟合
train_cat = X_train[category_column]
X_train = X_train[list(set(X_train.columns) - set(category_column))]
ohe.fit(train_cat)

# 转换训练集和测试集
train_encoded = ohe.transform(train_cat)
test_encoded = ohe.transform(X_test[category_column])
X_test = X_test[list(set(X_test.columns) - set(category_column))]
# 转换为DataFrame并保持列名一致
categories = ohe.categories_[0]
columns = [f"{item}_{category}" for item in category_column for category in categories]
train_ohe = pd.DataFrame(train_encoded, columns=columns, index=X_train.index)
test_ohe = pd.DataFrame(test_encoded, columns=columns, index=X_test.index)

# 合并回原DataFrame
X_train = pd.concat([X_train, train_ohe], axis=1)
X_test = pd.concat([X_test, test_ohe], axis=1)
print(X_train.head())
from sklearn.preprocessing import StandardScaler

# 初始化标准化器
scaler = StandardScaler()

# 只在训练集上拟合
scaler.fit(X_train)  # 计算训练集的均值和标准差

# 转换训练集和测试集
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)  # 使用训练集的参数
print(X_train)
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix, roc_auc_score
import pandas as pd

# 加载数据（假设df是DataFrame，y是目标列）
X = X_train
y = y_train

# 初始化模型
rf = RandomForestClassifier(
    n_estimators=1000,  # 树的数量
    max_depth=5,  # 树的最大深度
    random_state=42,
    max_features=3
)

# 训练模型
rf.fit(X_train, y_train)

# 预测
y_pred = rf.predict(X_train)
y_proba = rf.predict_proba(X_train)[:, 1]  # 预测正类的概率

# 评估
print(f"准确率: {accuracy_score(y_train, y_pred):.4f}")
print(f"AUC分数: {roc_auc_score(y_train, y_proba):.4f}")
print("\n混淆矩阵:")
print(confusion_matrix(y_train, y_pred))
y_pred = rf.predict(X_test)
result = pd.DataFrame(data_test["id"])
result["Personality"] = le.inverse_transform(y_pred)
result.to_csv("/kaggle/working/submission.csv", index=False)
print(result)